package pl.poznan.put.cs.idss.students.kingcart.core.capturer;

import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_8U;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateImage;
import static com.googlecode.javacv.cpp.opencv_core.cvDrawContours;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSize;
import static com.googlecode.javacv.cpp.opencv_highgui.CV_CAP_PROP_FPS;
import static com.googlecode.javacv.cpp.opencv_highgui.cvCreateFileCapture;
import static com.googlecode.javacv.cpp.opencv_highgui.cvGetCaptureProperty;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_ADAPTIVE_THRESH_GAUSSIAN_C;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_BGR2GRAY;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_CHAIN_APPROX_SIMPLE;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_RETR_LIST;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_THRESH_BINARY;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvAdaptiveThreshold;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvCanny;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvCvtColor;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvDilate;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvErode;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvFindContours;

import java.awt.Canvas;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import pl.poznan.put.cs.idss.students.kingcart.core.tracker.Tracker;
import pl.poznan.put.cs.idss.students.kingcart.ui.MainCanvas;

import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.FrameGrabber.Exception;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.CvContour;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class WebCamCapturer implements Capturer, ActionListener {

	final OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
	private Image cam = null;
	private MainCanvas canvas;
	private int fps;
	private Timer timer;
	private boolean track;
	private Tracker tracker;
	private IplImage frame;

	public Image getImage() {

		if (getFrame() == null) {
			return null;
		}
		// IplImage GrayImage = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
		//
		// cvCvtColor(img, GrayImage, CV_BGR2GRAY);
		//
		// IplImage BWImage = cvCreateImage(cvGetSize(GrayImage),
		// IPL_DEPTH_8U, 1);
		//
		// cvAdaptiveThreshold(GrayImage, BWImage, 255,
		// CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 45, -8);
		//
		// cvDilate(GrayImage, GrayImage, null, 5);
		// cvErode(GrayImage, GrayImage, null, 5);
		//
		// cvCanny(GrayImage, GrayImage, 5, 5, 5);
		//
		// CvSeq cvSeq = new CvSeq();
		// CvMemStorage memory = CvMemStorage.create();

		// cvFindContours(BWImage, memory, cvSeq,
		// Loader.sizeof(CvContour.class), CV_RETR_LIST,
		// CV_CHAIN_APPROX_SIMPLE);
		//
		// while (cvSeq != null && !cvSeq.isNull()) {
		// cvDrawContours(img, cvSeq, CvScalar.GREEN,
		// CvScalar.BLUE, 10, 1, 1);
		// cvSeq = cvSeq.h_next();
		// }

		cam = frame.getBufferedImage();

		// output.drawImage(cam);

		return cam;

	}

	public void initCapture() {
		try {
			grabber.start();
		} catch (com.googlecode.javacv.FrameGrabber.Exception e) {
			e.printStackTrace();
		}
		// obtain the frames per seconds of that video
		fps = (int) 24;
		timer = new Timer(2000 / fps, this);
		timer.start();
	}

	public void start(MainCanvas canvas) {
		this.canvas = canvas;
		initCapture();

	}

	public void stop() {
		if (timer.isRunning())
			timer.stop();
	}

	public void resumeAndTrack(Tracker tracker) {
		this.tracker = tracker;
		track = true;
		if (!timer.isRunning())
			timer.start();

	}

	public IplImage getFrame() {
		try {
			frame = grabber.grab();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return frame;
	}

	public void actionPerformed(ActionEvent arg0) {
		Image img = getImage();
		if (track) {
			IplImage trackImage = tracker.track(frame);
			canvas.drawNextFrame(trackImage.getBufferedImage());
		} else {
			canvas.drawNextFrame(img);
		}

	}

}
